package org.elsfs.cloud.common.mybatis.ext.sql;




import org.elsfs.cloud.common.mybatis.ext.sql.support.condition.ConditionItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.limit.LimitItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.order.CompositeOrderItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.order.OrderItem;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 可排序条件构建器抽象实现
 *
 * @param <C> 子类具体类型
 */
public abstract class AbstractSortableConditionBuilder<C extends AbstractSortableConditionBuilder<C>> extends AbstractSortableCondition<C> {

    /**
     * 条件项列表
     */
    private final List<ConditionItem> conditionItems = new ArrayList<>();
    /**
     * 聚合条件项
     */
    private final List<OrderItem> orderItems =  new ArrayList<>();
    /**
     * 限制数量项
     */
    private LimitItem limitItem;

    /**
     * 添加一个条件
     *
     * @param conditionItem 条件
     */
    @Override
    protected void addConditionItem(ConditionItem conditionItem) {
        this.conditionItems.add(conditionItem);
    }

    /**
     * 添加排序项
     *
     * @param orderItem 排序项
     */
    @Override
    protected void addOrderItem(OrderItem orderItem) {
        this.orderItems.add(orderItem);
    }

    /**
     * 设置限制数量项
     *
     * @param limitItem 限制数量项
     */
    @Override
    protected void setLimitItem(LimitItem limitItem) {
        this.limitItem = limitItem;
    }

    /**
     * 构建SQL之前处理
     */
    @Override
    protected void beforeBuild() {
        if (!this.conditionItems.isEmpty()) {
            this.addSqlFragment(
                new TokenSqlFragment(
                    String.format(
                        "WHERE  %s",
                        ConditionItem.stripHeaderKeyword(
                            this.conditionItems.stream()
                                .map(SqlFragment::buildSqlFragment)
                                .collect(Collectors.joining(" "))
                        )
                    )
                )
            );
        }
        if (!this.orderItems.isEmpty()) {
            this.addSqlFragment(
                new CompositeOrderItem(this.orderItems)
            );
        }
        if (this.limitItem != null) {
            this.addSqlFragment(this.limitItem);
        }
    }
}
